package com.ziq.zcamp.activities

import android.text.TextUtils
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gmlive.camp.data.exception.LocalException
import com.ziq.base.extension.launchWithTryAsynchronous
import com.ziq.zcamp.R
import com.ziq.zcamp.api.repository.ActivitiesRepository
import com.ziq.zcamp.api.repository.DefaultActivitiesRepository
import com.ziq.zcamp.api.service.NetWorkException
import com.ziq.zcamp.api.service.ServiceModule.Companion.onApiFail
import com.ziq.zcamp.bean.activities.*
import com.ziq.zcamp.bean.place.VrInfo
import com.ziq.zcamp.bean.post.ImageInfo
import com.ziq.zcamp.bean.product.ProductRepertoryItem
import com.ziq.zcamp.constant.MerchantType
import com.ziq.zcamp.manager.GlobalContextManager
import com.ziq.zcamp.manager.MerchantManager
import com.ziq.zcamp.manager.UserManager
import com.ziq.zcamp.view.StatusView
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.text.DecimalFormat
import javax.inject.Inject

/**
 * 活动详情 ViewModel
 */
@HiltViewModel
class ActivitiesDetailsViewModel @Inject constructor() : ViewModel() {

    var id : Long?= null
        private set
    var info : ActivitiesInfo?= null
        private set

    val poster : MutableLiveData<ImageInfo> = MutableLiveData()
    val name : MutableLiveData<String> = MutableLiveData()
    val time : MutableLiveData<String> = MutableLiveData()
    val price : MutableLiveData<String> = MutableLiveData()
    val location : MutableLiveData<String> = MutableLiveData()
    val camp : MutableLiveData<ActivitiesCampInfo> = MutableLiveData()
    val organizer : MutableLiveData<ActivitiesOrganizerInfo> = MutableLiveData()
    val content : MutableLiveData<MutableList<ActivitiesContentInfo>> = MutableLiveData()
    val showLaunchActivities : MutableLiveData<Boolean> = MutableLiveData(false)
    val freeType = MutableLiveData<Int>()
    val actStatus : MutableLiveData<Int> = MutableLiveData()
    val statusShow = MutableLiveData(StatusView.NO_DATA)

    val ticketData : MutableLiveData<MutableList<ActivitiesTicketsInfo>> = MutableLiveData()
    val inventoryData : MutableLiveData<MutableList<ProductRepertoryItem>> = MutableLiveData()

    val isOffLine = MutableLiveData<Boolean>()
    val ticketError = MutableLiveData<Boolean>()

    val vrInfo = MutableLiveData<VrInfo>()

    private val mRepository : ActivitiesRepository by lazy {
        DefaultActivitiesRepository()
    }

    fun init(id: Long, info: ActivitiesInfo?) {
        ActivitiesDetailsViewModel@this.id = id
        ActivitiesDetailsViewModel@this.info = info

        if (info!=null){
            setActivityData(info)
        }

        showLaunchActivities.value = UserManager.instance.userInfo.value?.let {
            when(MerchantManager.instance.obtainMerchantType()){
                MerchantType.act.value, MerchantType.camp.value -> false
                else -> true
            }
        }
    }

    private fun setActivityData(info: ActivitiesInfo){
        isOffLine.value = info.status == 1
        if (info.status == 1)
            return

        info.images?.let {
            if (it.isNotEmpty()){
                poster.value = it[0]
            }
        }
        name.value = info.title
        if (info.start_show_time != null && info.end_show_time!= null){
            if (info.start_show_time.equals(info.end_show_time)){
                time.value = "${info.start_show_time}"
            }else{
                time.value = "${info.start_show_time}-${info.end_show_time}"
            }
        }else if (info.start_show_time!=null){
            time.value = "${info.start_show_time}"
        }else{
            time.value = "--:--"
        }
        location.value = info.location_addr
        camp.value = info.related_camp
        organizer.value = info.organizer

        if (!info.price_range.isNullOrEmpty() && info.free_type != 1){
            val min = info.price_range?.minOrNull()
            val string = DecimalFormat("0.00").format((min?:0) / 100f)
            price.value =  "￥$string 起"
        }else if ( info.free_type == 1){
            price.value =  "免费"
        }else{
            price.value =  ""
        }

        freeType.value = info.free_type
        actStatus.value = info.act_status

        vrInfo.value = info.vr
    }

    fun getActiveContactNumber():String{
        return info?.phone?:""
    }

    fun requestData() {
        launchWithTryAsynchronous(whenTry = {
            if (id == null){
                throw LocalException(0,"")
            }
            if (content.value.isNullOrEmpty()){
                statusShow.postValue(StatusView.LOADING)
            }
            val result = mRepository.obtainActivityDetails(id!!)
            val contentList = mutableListOf<ActivitiesContentInfo>()
            if (!result.content_detail.isNullOrEmpty()){
                for (item in result.content_detail!!){
                    if ((item.type?:0)==2 && TextUtils.isEmpty(item.content)){
                        continue
                    }else{
                        contentList.add(item)
                    }
                }
            }
            if (!result.other_info?.introduce_info.isNullOrEmpty()){
                for (item in result.other_info?.introduce_info!!){
                    transformation(item,"票种介绍")
                }
                contentList.addAll(result.other_info?.introduce_info!!)
            }
            if (!result.other_info?.path_info.isNullOrEmpty()){
                for (item in result.other_info?.path_info!!){
                    transformation(item,"活动流程")
                }
                contentList.addAll(result.other_info?.path_info!!)
            }
            if (!result.other_info?.buy_ticket_info.isNullOrEmpty()){
                for (item in result.other_info?.buy_ticket_info!!){
                    transformation(item,"购票须知")
                }
                contentList.addAll(result.other_info?.buy_ticket_info!!)
            }
            if (!result.other_info?.join_notice_info.isNullOrEmpty()){
                for (item in result.other_info?.join_notice_info!!){
                    transformation(item,"参与须知")
                }
                contentList.addAll(result.other_info?.join_notice_info!!)
            }
            content.postValue(contentList)
            info = result
            withContext(Dispatchers.Main){
                setActivityData(result)
            }
            if (contentList.isNullOrEmpty()){
                statusShow.postValue(StatusView.NO_DATA)
            }else{
                statusShow.postValue(StatusView.IDLE)
            }
        }, whenCatch = {
            statusShow.postValue(StatusView.NET_ERROR)
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onApiFail(it.errorMsg)
                        if (it.errorCode == 12011){
                            isOffLine.postValue(true)
                        }
                    }
                    is LocalException -> {
                        when(it.errorCode){
                            in 1001..1005->{
                                onApiFail(GlobalContextManager.getString(R.string.all_net_error))
                            }
                            else -> {
                                onApiFail(GlobalContextManager.getString(R.string.data_error))
                            }
                        }
                    }
                }
            }
        })
    }

    private fun transformation(item : ActivitiesContentInfo,str : String):ActivitiesContentInfo{
        val data = ActivitiesThemeInfo()
        data.desc = item.content
        data.title = str
        item.type = 3
        item.theme = data
        return item
    }

    fun obtainTicketInfo(){
        launchWithTryAsynchronous(whenTry = {
            if (id == null){
                onApiFail(GlobalContextManager.getString(R.string.data_error))
                throw LocalException(0,"")
            }
            val result = mRepository.activitiesTicketList(id!!)
            ticketData.postValue(result.toMutableList())
        }, whenCatch = {
            ticketError.postValue(true)
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onApiFail(it.errorMsg)
                    }
                    is LocalException -> {
                        when(it.errorCode){
                            in 1001..1005->{
                                onApiFail(GlobalContextManager.getString(R.string.all_net_error))
                            }
                            else -> {
                                onApiFail(GlobalContextManager.getString(R.string.data_error))
                            }
                        }
                    }
                }
            }
        })
    }

    private fun getInventoryInfo(id:String){
        launchWithTryAsynchronous(whenTry = {
            val result = mRepository.ticketRepertoryList(id)
            inventoryData.postValue(result.toMutableList())
        }, whenCatch = {
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onApiFail(it.errorMsg)
                    }
                    is LocalException -> {
                        onApiFail(GlobalContextManager.getString(R.string.all_net_error))
                    }
                }
            }
        })
    }

    private var selectedTicket : ActivitiesTicketsInfo? = null
    fun selectedTicketType(info: ActivitiesTicketsInfo) {
        selectedTicket = info
        getInventoryInfo(info.ticket_id?:"")
    }

    fun getSelectedTicket():ActivitiesTicketsInfo? {
        selectedTicket?.let {
            it.image = poster.value?.url
            it.actName = name.value
            it.active_id = id
            it.is_identity = info?.is_identity
        }
        return selectedTicket
    }
}